<?php
abstract class Controller {
	protected $registry;
	protected $route;
	protected $method; //current call method
	protected $id;
	protected $layout;
	protected $template;
	protected $children = array();
	protected $data = array();
	protected $output;
	protected $messages;
	protected $language;
	protected $_; //a ref to language data
	
	public function __construct($registry, $route = '', $method = '') {
		$this->registry = $registry;
		$this->route = $route;
		$this->method = $method;
		$this->messages = array();
		$this->language = new Language(null, $this->registry->get('language'));
		$this->_ = & $this->language->all();
	}

	public function __get($key) {
		return $this->registry->get($key);
	}

	public function __set($key, $value) {
		$this->registry->set($key, $value);
	}
	
	protected function forward($route, $args = array()) {
		return new Action($route, $args);
	}

	protected function redirect($url, $status = 302) {
		header('Status: ' . $status);
		header('Location: ' . str_replace(array('&amp;', "\n", "\r"), array('&', '', ''), $url));
		exit();
	}
	
	//cache function enhance
	protected function getChild($child, $args = array(), $cache = FALSE, $expire = 1200) {
		$action = new Action($child, $args);
		if ($cache) {
			$output = $this->cache->get( 'module::' . $cache);
			if ($output) return $output;
		}

		if (file_exists($action->getFile())) {
			require_once($action->getFile());
			$class = $action->getClass();
			$controller = new $class($this->registry, $action->getRoute(), $action->getMethod());
			$controller->{$action->getMethod()}($action->getArgs());
			if ($cache) $this->cache->set('module::' . $cache, $controller->output, $expire);
			return $controller->output;
		} else {
			trigger_error('Error: Could not load controller ' . $child . '!');
			exit();
		}
	}

	private function _resolveTpl($tpl) {
		if (defined('CATALOG')) {				
			if (IS_MOBILE) {
				$mobile_tpl = str_replace('.', '_mobile.', $tpl);
				if (file_exists(DIR_TEMPLATE . C('config_template') . '/template/' . $mobile_tpl)) {
					return DIR_TEMPLATE . C('config_template') . '/template/' . $mobile_tpl;	
				}
			}

			if (file_exists(DIR_TEMPLATE . C('config_template') . '/template/' . $tpl)) {
				return DIR_TEMPLATE . C('config_template') . '/template/' . $tpl;
			} else {
				return DIR_TEMPLATE . 'default/template/' . $tpl;
			}
		}
		else return DIR_TEMPLATE . $tpl;
	}

	protected function render($tpl = null, $children = true) {
		if (function_exists('theme_before_render')) {
			theme_before_render($this);
		}
		
		if ($tpl) {
			$this->template = $this->_resolveTpl($tpl);
		}
		elseif ($this->template && !file_exists($this->template)) {
			$this->template = $this->_resolveTpl($this->template);
		}
		
		if ($children) {
			foreach ($this->children as $child) {
				$this->data[basename($child)] = $this->getChild($child);
			}
		}
		
		if (file_exists($this->template)) {
			$_ = & $this->_;
			
			extract($this->messages);
			extract($this->data);
			
      		ob_start();
	  		require($this->template);
	  		$this->output = ob_get_contents();
      		ob_end_clean();
			return $this->output;
    	} else {
			trigger_error('Error: Could not load template ' . $this->template . '!');
			exit();
    	}
	}

	public function display($tpl = null, $children = true) {
		$this->response->setOutput($this->render($tpl, $children));
	}

	protected function setMessage($key, $msg) {
		$this->messages[$key] = $msg;
	}
}